<?php
namespace app\api\model;
use think\Cache;
use app\common\library\helper;

/**
 * 购物车管理
 */
class Cart
{
    public $error = '';	//错误信息
    private $user_id;	//用户id
	private $shop_id;	//门店id
    private $cart = [];	//购物车列表
    private $clear = false;	//是否清空购物车

    /**
     * 构造方法
     */
    public function __construct($user_id,$shop_id)
    {
        $this->user_id = $user_id;
		$this->shop_id = $shop_id;
        $this->cart = Cache::get('cart_' . $this->user_id . '_' . $this->shop_id) ?: [];
    }
	
	 /**
     * 获取购物车内容
     */
    public function getCart()
    {
		return $this->cart;
	}

    /**
     * 购物车列表
     */
    public function getList($user,$food_mode=0,$location='')
    {
		$delivery = Setting::getItem('delivery');//获取配送设置
        // 商品列表
        $goodsList = [];
        $goodsIds = array_unique(array_column($this->cart, 'goods_id'));
        foreach ((new Goods)->getListByIds($goodsIds) as $goods) {
            $goodsList[$goods['goods_id']] = $goods;
        }
        // 是否存在收货地址
        $exist_address = !$user['address']->isEmpty();
        
		$pack_price = 0;//餐盒费
        // 购物车商品列表
        $cartList = [];
        foreach ($this->cart as $key => $cart) {
            // 判断商品不存在则自动删除
            if (!isset($goodsList[$cart['goods_id']])) {
                $this->delete($cart['goods_id'], $cart['goods_sku_id']);
                continue;
            }
            $goods = clone $goodsList[$cart['goods_id']];
            // 商品sku信息
            $goods['goods_sku_id'] = $cart['goods_sku_id'];
            // 商品sku不存在则自动删除
            if (!$goods['goods_sku'] = $goods->getGoodsSku($cart['goods_sku_id'])) {
                $this->delete($cart['goods_id'], $cart['goods_sku_id']);
                continue;
            }
            // 判断商品是否下架
            if ($goods['goods_status']['value'] != 10) {
                $this->setError('很抱歉，商品 [' . $goods['goods_name'] . '] 已下架');
            }
            // 判断商品库存
            if ($cart['goods_num'] > $goods['goods_sku']['stock_num']) {
                $this->setError('很抱歉，商品 [' . $goods['goods_name'] . '] 库存不足');
            }
			//计算餐盒费
			if($food_mode==2 OR $food_mode==3){
				if($goods['pack_price']>0){
					$pack_price = $pack_price + $goods['pack_price']*$cart['goods_num'];
				}
			}
			//如果是外卖 - 计算价格
			if($food_mode==3){
				// 商品单价
				$goods['goods_price'] = $goods['goods_sku']['out_price'];
				// 商品总价
				$goods['total_num'] = $cart['goods_num'];
				$goods['total_price'] = $total_price = bcmul($goods['goods_price'], $cart['goods_num'], 2);
			}else{
				//非外卖
				// 商品单价
				$goods['goods_price'] = $goods['goods_sku']['goods_price'];
				// 商品总价
				$goods['total_num'] = $cart['goods_num'];
				$goods['total_price'] = $total_price = bcmul($goods['goods_price'], $cart['goods_num'], 2);
			}
            $cartList[] = $goods->hidden(['category', 'content', 'spec']);
        }
        // 商品总金额
        $orderTotalPrice = helper::getArrayColumnSum($cartList, 'total_price');
		//计算优惠金额
		$activity_price = 0.00;
		//满减活动
		$mActivity = (new Activity)->where(['activity_type'=>10])->order(['min_price' => 'desc'])->select();	
		//如果活动存在
		if($mActivity){
			for($n=0;$n<sizeof($mActivity);$n++){
				if($mActivity[$n]['min_price']<=$orderTotalPrice){
					$activity_price = $activity_price + $mActivity[$n]['reduce_price'];
					break;
				}
			}
		}
		//首单立减活动
		$jActivity = (new Activity)->where(['activity_type'=>20])->find();	
		//查询是否是首单
		$orderCount = (new Order)->where([
			'pay_status'=> 20,
			'user_id'=> $user['user_id']
		])->count();
		//如果活动存在
		if($jActivity AND $orderCount==0){
			$activity_price = $activity_price + $jActivity['reduce_price'];
		}
		//计算实际支付金额
		if($orderTotalPrice>=$activity_price){
			if($orderTotalPrice==$activity_price){
				$order_pay_price = 0.01;
			}else{
				$order_pay_price = $orderTotalPrice - $activity_price;
			}
		}else{
			$order_pay_price = 0.01;
		}
		// 订单配送费用
        $expressPrice = 0;
		$min_price = 0;
		//餐盒费加入总价
		if($pack_price>0){
			$order_pay_price = $order_pay_price + $pack_price;
		}
		// 商品是否在配送范围
        $intraRegion = true;
		//如果是外卖 +配送费用
		if($food_mode==3){
			if($user['address_default']){
				//如果免费派送范围大于0
				$shop = Shop::detail($this->shop_id);
				$result = getDistance($user['address_default']['location'],$shop['coordinate']); //计算距离
				if($result){
					$distance = $result[0]['distance'];//获取距离计算结果
					if($delivery['delivery_range'] < $distance){
						$intraRegion = false;
					}
					if($delivery['free_range']>0){
						if($delivery['free_range'] < $distance){ //如果超出免费区域就增加配送费
							$expressPrice = $delivery['delivery_price'];
							$order_pay_price = $order_pay_price + $expressPrice;
						}
					}else{
						$expressPrice = $delivery['delivery_price'];
						$order_pay_price = $order_pay_price + $expressPrice;
					}
				}else{//定位错误加配送费
					$expressPrice = $delivery['delivery_price'];
					$order_pay_price = $order_pay_price + $expressPrice;
				}
			}
			//计算最低配送价格范围
			if($orderTotalPrice<$delivery['min_price']){
				$min_price = $delivery['min_price'] - $orderTotalPrice;					
			}			
		}
        return [
            'goods_list' => $cartList,                       // 商品列表
            'order_total_num' => $this->getTotalNum(),       // 商品总数量
            'order_total_price' => helper::number2($orderTotalPrice),              // 商品总金额 (不含运费)
            'order_pay_price' => helper::number2($order_pay_price),    // 实际支付金额
			'activity_price' => helper::number2($activity_price),	// 优惠金额
			'min_price' => $min_price,	// 起送价价
			'pack_price' => helper::number2($pack_price),	// 餐盒费用
            'address' => $user['address_default'],  // 默认地址
            'exist_address' => $exist_address,      // 是否存在收货地址
            'express_price' => helper::number2($expressPrice),       // 配送费用
            'intra_region' => $intraRegion,         // 当前用户收货城市是否存在配送规则中
            'has_error' => $this->hasError(),
            'error_msg' => $this->getError(),
        ];
    }

    /**
     * 添加购物车
     */
    public function add($goods_id, $goods_num, $goods_sku_id = 0)
    {
        // 购物车商品索引
        $index = $goods_id . '_' . $goods_sku_id;
        // 商品信息
        $goods = Goods::detail($goods_id);
        // 商品sku信息
        $goods['goods_sku'] = $goods->getGoodsSku($goods_sku_id);
        // 判断商品是否下架
        if ($goods['goods_status']['value'] != 10) {
            $this->setError('很抱歉，该商品已下架');
            return false;
        }
        // 判断商品库存
        $cartGoodsNum = $goods_num + (isset($this->cart[$index]) ? $this->cart[$index]['goods_num'] : 0);
        if ($cartGoodsNum > $goods['goods_sku']['stock_num']) {
            $this->setError('很抱歉，商品库存不足');
            return false;
        }
        $create_time = time();
        $data = compact('goods_id', 'goods_num', 'goods_sku_id', 'create_time');
        if (empty($this->cart)) {
            $this->cart[$index] = $data;
            return true;
        }
        isset($this->cart[$index]) ? $this->cart[$index]['goods_num'] = $cartGoodsNum : $this->cart[$index] = $data;
        return true;
    }

    /**
     * 减少购物车中某商品数量
     */
    public function sub($goods_id, $goods_sku_id)
    {
        $index = $goods_id . '_' . $goods_sku_id;
        $this->cart[$index]['goods_num'] > 1 && $this->cart[$index]['goods_num']--;
    }

    /**
     * 删除购物车中指定商品
     */
    public function delete($goods_id, $goods_sku_id)
    {
        $index = $goods_id . '_' . $goods_sku_id;
        unset($this->cart[$index]);
    }

    /**
     * 获取当前用户购物车商品总数量
     */
    public function getTotalNum()
    {
        return array_sum(array_column($this->cart, 'goods_num'));
    }

    /**
     * 析构方法
     * 将cart数据保存到缓存文件
     */
    public function __destruct()
    {
        $this->clear !== true && Cache::set('cart_' . $this->user_id . '_' . $this->shop_id, $this->cart, 86400);
    }

    /**
     * 清空当前用户购物车
     */
    public function clearAll()
    {
        $this->clear = true;
        Cache::rm('cart_' . $this->user_id . '_' . $this->shop_id);
    }

    /**
     * 设置错误信息
     */
    private function setError($error)
    {
        empty($this->error) && $this->error = $error;
    }

    /**
     * 是否存在错误
     */
    private function hasError()
    {
        return !empty($this->error);
    }

    /**
     * 获取错误信息
     */
    public function getError()
    {
        return $this->error;
    }

}
